<template>
  <div ref="canvasDiv"  :id="canvasId" class="container"></div>
</template>
<script>
//引入绘图插件
import { DataManager } from '../../assets/layout/kylin.min.js';
import "../../assets/layout/kylin.css";
import baseComp from "./baseComp";
import elementResizeDetectorMaker from "element-resize-detector";
export default {
  name: "layoutComps",
  // model: {
  //   prop: "viewData",
  //   event: "returnDataChange",
  // },
  props:{
    viewData:{
      type: Object,
        default: () => {
        }
    },
    canvasWs:
      {type: Object,
        default: () => {
        }
      },
    scale:
      {
        type: Object,
        default: () => {
        }
      },
    coord:
      {
        type: Object,
        default: () => {
        }
      }
  },
  extends: baseComp,
  data() {
    return {
      scaleDatas:[],//比例尺数据
      canvasManager:{},
      coordData:"bottom-left",//当前坐标系
      projectId: "", //工程资源id
      viewType: "", //绘图类型
      canvasType: "",//转换后绘图类型
      canvasId:"", //当前动态绘图id
      scaleData:"mm",//当前比例尺
      projectData:{},
      diePhysicForm:[], //芯片组成信息
      canvaSizeWidth: 0,
      canvaSizeHeight: 0,
      tempNodes:{},//新增节点数临时存储
      originalObject:this.$route.query,
      erd: null, //容器大小变化监听
      initEnable: false, //是否是初始化第一次加载
      pelMaxNum: 1000, //图元阈值
      pelNum: 100, //当前图元数量
  }
},
watch:{
  originalObject: {
          handler(val){
              if(val){
                  // console.log("登录用户："+val.user+" 登录密码:"+val.pwd);
                  if(val.defaultLoad){
                    console.log("默认根据用户创建加载类原理图");
                    this.defaultInitCanvas(val.projectName,val.viewType,this);
                  }
              }
          },
          deep: true, // 深度观察监听 设置为 true
          immediate: true, // 第一次初始化渲染就可以监听到
      }
},
created() {

},
mounted(){
  console.log("绘图渲染完毕");
  this.windowsListener();
  this.erd = elementResizeDetectorMaker();

},
beforeDestroy() {
  let container = document.getElementById(this.canvasId);
  this.erd.uninstall(container)
},
methods:{
  /**
   * 启动监听外部界面发送过来数据
   */
   windowsListener(){
    let that = this;
    window.addEventListener("clickNode",function(event){
      let receiveMsg = event.data;
      console.log("接收到外部发送过来节点节点交互数据："+receiveMsg);
      // 那个第一个参数是 type，传 'id' / 'name'
      // 第二个是值
      that.canvasManager.setNodeSelected('name', receiveMsg.name, true)
      // let nodeId = "";
      // this.dataManager.selectNodeWithId(nodeId);
    });
    document.onkeydown = function(event) {
      if (event.keyCode === 46 && that.canvasManager) {
        console.log("用户删除");
        let nodes = that.canvasManager.getSelectedNodes()
        if(nodes){
          that.delNode(nodes);
          that.canvasManager.deleteSelectedNode()
        }

      }
    };
   },
   /**
    * 视图窗口大小调整触发 窗口过滤事件
    * @param {*} that
    */
   handleResize(ele){
    let canvasWidth =  ele.offsetWidth;
    let canvasHeight =  ele.offsetHeight;
    if(this.initEnable){
      let waferInfo = this.getCWafer();
      let square = waferInfo.square;
      //当边框宽拖动 》初始化化宽度时 重新绘图
      if(this.canvaSizeWidth < canvasWidth && canvasWidth <= square){
        this.canvaSizeWidth = canvasWidth;
        this.viewLayout();
        return;
      }
      if(this.canvaSizeHeight < canvasHeight && canvasHeight <= square){
        this.canvaSizeHeight = canvasHeight;
        this.viewLayout();
        return;
      }
    }
   },
   /**
    * 默认初始化类原理图
    */
   async defaultInitCanvas(projectName,viewType,that){
    let rdata = await that.getData(that,"get","/uavMesh/layout/getProjectByName?projectName="+projectName,null);
    console.log("获取到当前工程数据"+JSON.stringify(rdata));
    if(rdata.data.code == 200){
      that.initLayoutCanvas(rdata.data.data,viewType)
    }else{
      this.$message.warning(rdata.data.msg);
    }

   },

   /**初始化布局绘图
    *
    * @param {*} projectId
    * @param {*} viewType
    */
   initLayoutCanvas(projectId,viewType){
    this.projectId = projectId;
    this.viewType = viewType;
    this.canvasId = projectId+"."+viewType;
    this.scaleData = "mm";
    if(this.viewType == "D"){
      this.canvasType = "0";
    }else if(this.viewType == "E"){
      this.canvasType = "1";
    }else if(this.viewType == "F"){
      this.canvasType = "2";
    }
    this.loadCanvas(this.projectId,this.viewType);
   },

   loadCanvas(projectId,viewType){
    let that = this;
    this.$nextTick(() => {
      that.initCanvas(that)
    });
    this.executeEvent('loadCanvas', this.path, projectId,viewType)
  },
  /**
   * 加载画布初始化参数
   * @param {*} that
   */
   async initCanvas(that){
    //初始化订阅
    that.wsSubscribe(that);
    //获取比例尺数据
    let scaleData = await that.getData(that,that.scale.method,that.scale.url,null);
    if(scaleData == 0){
      console.log("未获取到比例尺数据");
    }
    that.scaleDatas = scaleData.data.data;
    //获取工程数据
    let searchParam = {"resId":that.projectId};
    let projectDatatemp = await that.getData(that,"post","/uavMesh/layout/queryProjectData",searchParam);
    if(projectDatatemp.status = "200"){
      that.projectData = projectDatatemp.data.data;
      if(that.projectData["diePhysicForm"]){
        that.diePhysicForm =  that.projectData["diePhysicForm"];
        that.waferCdata = that.projectData["waferForm"];
      }
    }
    let container = document.getElementById( that.canvasId);
    that.erd.listenTo(container,that.handleResize)
    that.initLayout(that);

  },
    /**
   * 初始化绘图
   */
  async initLayout(that){
    console.log("加载布局绘图 当前项目工程："+that.projectId+" 视图类型："+that.viewType+" ");
    let axjx = that.$myAxios;
    that.canvasManager = new DataManager();
    let container = document.getElementById( that.canvasId); //that.$parent.$el;//
    that.canvaSizeWidth = container.offsetWidth;
    that.canvaSizeHeight = container.offsetHeight;
    await that.canvasManager.initGlobalData({
      resId: that.projectId,
      httpUrlBase: '/zeroTrustAuthPlatform',
      axiosProxy: axjx,
      wsBaseHost: 'ws://192.168.6.30:10100/uavMesh/ueye',
      scaleDatas: that.scaleDatas, // 比例尺
      coordData: that.coordData, // 当前坐标系
      currentScale: that.scaleData, // 当前比例尺
      viewMoveMinLength: 30, // 移动触发视口变换阈值
      wsIsNative: false, // 使用本地ws
        // 视图部分
      viewOptions: {
        type: that.canvasType,
        container: container,
        canvaSize: {
            width: that.canvaSizeWidth,
            height: that.canvaSizeHeight
        },
        viewPortSize:{
            width: that.canvaSizeWidth,
            height: that.canvaSizeHeight
        },
        backgroundColor: '#ffffff',
        markerColor: '#ffffff',
        markerSize: 10
    }
    });
    const sceneApp = that.canvasManager.currentRenderApp;
    if(that.canvasType == "0"){
      window.scene3dApp = sceneApp;
      sceneApp.initSceneWithData({});
      // 启动场景App
      sceneApp.start();
    }

    that.initEnable = true;
  },
  /**
   * 调用后端过滤处理
   */
  viewLayout(){
    console.log("触发绘图过滤事件，调用后台接口");
    let searchParam = {
      "resId": this.projectId,
      "coordAResId": this.coordAResId,
      "scaleResId": this.scaleData,
      "viewType": this.canvasType,
      "viewWide": this.canvaSizeWidth,
      "viewHigh": this.canvaSizeHeight,
      "moveX": "0",
      "moveY": "0"
    };
    that.getData(that,"post","/uavMesh/layout/getViewLayoutDatas",searchParam);
  },
  /**
   * 接收节点拖入事件
   * @param {*} node
   */
  tagNode(node){
    console.log("拖拽节点进入");
    //let nodes = this.canvasManager.convertDomPosToCanvasPos({x: node.x, y: node.y})
    // let wafer = this.getWaferNow();
    let container = document.getElementById( this.canvasId);
    let rect = container.getBoundingClientRect();
    let w = window.innerWidth;
    let h = window.innerHeight;
    // var topDistance = rect.top;
    // var bottomDistance = windowHeight - rect.bottom;
    // var leftDistance = rect.left;
    // var rightDistance = windowWidth - rect.right;
    node.x = node.x - w/2 - rect.left/2;
    node.y = h/2 -node.y - rect.top/2;
    this.addNode(node)
  },
  /**
   *
   * @param {新增节点} node
   */
  addNode(node){
    console.log(node);
    const tempnode =this.physicDieDeal(node);
    for(let i = 0; i< tempnode.length; i++){
      let die = tempnode[i];
      if(node.classify==die.classify && node.type == die.type){
          let nodeName ="";
          if(this.tempNodes[node.classify]){
            let num = this.tempNodes[node.classify]+1;
             nodeName = node.classify+num;
             this.tempNodes[node.classify] = num;
          }else{
            nodeName = node.classify+"1";
            this.tempNodes[node.classify] = 1;
          }

          let nodetemp = {
            id: new Date().getTime() + Math.random().toString(36).substr(2),
            name: nodeName,
            type: node.type,
            group: 0,
            pos: {
              x: parseInt(node.x),
              y: parseInt(node.y),
            },
            size: {
              width: die.sizeX,
              height: die.sizeY,
              thickness: node.thickness
            },
            rotation: 0,
            style: {
              color: node.color
            }
        };
        this.canvasManager.addNewNode(nodetemp)
        this.canvasManager.setNodeSelected('name',nodeName, true)
      }
    }
  },
  async addNodeDeal(node,that){
    node["projectId"] =  that.projectId;
    node["coord"] =  that.coordData;
    node["scale"] =  that.scaleData;
    const tempNode = {
      resId: that.projectId,
      coordAResId: that.coordData,
      scaleResId: that.scaleData,
      viewDieForm: {
        "type":node.classify,
				"name":node.type,
				"label":node.type,//图元显示名称
				"rotation":relativePos,//预制件旋转角度
				"group":"-1"
      }
    };
    //将节点数据
    let projectDatatemp = await that.getData(that,"post","/uavMesh/layout/addDieNode",tempNode);
    if(projectDatatemp.status = "200"){
      that.projectData = projectDatatemp.data.data;
    }
  },
  /**
   * 处理工程方案中芯片组成信息
   * @param {*} node
   */
  physicDieDeal(node){
    //进行物理组成数据判断
    let enable = true; //判断当前工程中是否存在该类型的芯片
    for(let i = 0; i< this.diePhysicForm.length; i++){
      let die = this.diePhysicForm[i];
      if(node.classify==die.classify && node.type == die.type && die.coordType == this.coordData){
        die.num = parseInt(die.num) +1;
        enable = false;
      }
    }
    if(enable){
      this.diePhysicForm.push({
        "classify": node.classify,
        "sizeX": node.sizeX,
        "coordType": this.coordData,
        "thickness": node.thickness,
        "num": 1,
        "type": node.type,
        "sizeY": node.sizeY
      });
      for(let i = 0; i < this.scaleDatas.length; i++){
        let scales = this.scaleDatas[i];
        this.diePhysicForm.push({
          "classify": node.classify,
          "sizeX": this.unitCalc(scales.unit,node.sizeX,scales.value),
          "coordType": scales.unit,
          "thickness": this.unitCalc(scales.unit,node.thickness,scales.value),
          "num": 1,
          "type": node.type,
          "sizeY": this.unitCalc(scales.unit,node.sizeY,scales.value),
      });
      }
    }
    const diephysics = {};
    diephysics["projectId"] = this.projectId;
    diephysics["diePhysicForm"] = this.diePhysicForm;
    //将节点数据
    this.getData(this,"post","/uavMesh/layout/uploadPhysic",diephysics).then((res) => {
        if (res.data.code == 200) {
          console.log("更新方案预制件组成成功");

        }else {
            console.log("更新方案预制件组成失败");
        }
    });

    return this.getDiesGroup(this.scaleData);
  },
  /**
   * 获取预制件组成
   * @param {*} coorde
   */
  getDiesGroup(coorde){
    let tempDie = [];
    if(this.diePhysicForm){
      for(let i = 0 ;i < this.diePhysicForm.length; i++){
        let die = this.diePhysicForm[i];
        if(die.coordType == coorde){
          tempDie.push(die);
        }
      }
    }

    return tempDie;
  },
  /**
   * 获取当前C晶圆片信息
   */
  getCWafer(){
    let waferCInfo = null;
    if(this.projectData["waferForm"]){
      this.projectData["waferForm"].forEach(element => {
        if(element.coordType == this.scaleData){
          waferCInfo = element;
        }
      });
    }
    return waferCInfo;
  },
  /**
   * 删除选中节点
   * @param {*} node
   */
  delNode(node){
    let tempName = "";
    for(let i = 0; i< this.diePhysicForm.length; i++){
      let die = this.diePhysicForm[i];
      if(node.type == die.type && die.coordType == this.coordData){
        die.num = die.num - 1;
        if( die.num == 0){
          tempName = die.type;
        }
      }
    }
    this.diePhysicForm = this.diePhysicForm.filter(tab => tab.type !== tempName);
    const diephysics = {};
    diephysics["projectId"] = this.projectId;
    diephysics["diePhysicForm"] = this.diePhysicForm;
    //将节点数据
    this.getData(this,"post","/uavMesh/layout/uploadPhysic",diephysics).then((res) => {
        if (res.data.code == 200) {
          console.log("更新方案预制件组成成功");

        }else {
            console.log("更新方案预制件组成失败");
        }
    });
  },
  /**
   * 物理单位转换
   * @param {} unit
   * @param {*} value
   */
  unitCalc(unit,value,scaleVal){
    let rval = 0;
    const tempval = value.split(" ");
    switch (unit) {
      case "mm":
        switch (tempval[1]) {
          case "mm":
            rval = tempval[0] * scaleVal;
            break;
          case "μm":
            rval = tempval[0] * scaleVal /1000;
            break;
          case "nm":
            rval = tempval[0] * scaleVal /1000/1000;
            break;
          default:
            break;
        }
        break;
      case "μm":
      switch (tempval[1]) {
          case "mm":
            rval = tempval[0] * scaleVal * 1000;
            break;
          case "μm":
            rval = tempval[0] * scaleVal ;
            break;
          case "nm":
            rval = tempval[0] * scaleVal /1000;
            break;
          default:
            break;
        }
        break;
      case "nm":
      switch (tempval[1]) {
          case "mm":
            rval = tempval[0] * scaleVal * 1000 * 1000;
            break;
          case "μm":
            rval = tempval[0] * scaleVal * 1000;
            break;
          case "nm":
            rval = tempval[0] * scaleVal ;
            break;
          default:
            break;
        }
        break;
      default:
        break;
    }
    return rval;
  },
    //***发送请求****
  getData(that,method, url, params) {
    try {
      return that.$myAxios.request(method, url, params).then((res) => {
        return res;
      });
    } catch (e) {
      return 0;
    }
  },
  /**
   * 根据不同布局类型绘制不同3d/2d图
   * resId：当前工程资源id
   * type：0-晶圆级 1-floorplan级 2-引脚级
   */
  draw(resId,type){
    /**
     * 调用插件进行画布初始化 传入参数
     * resId:当前工程资源id
     * type：0-晶圆级 1-floorplan级 2-引脚级
     * coordAResId:坐标系资源id
     * scaleResId：比例尺资源id
     */
    this.$Layout.drawNode(resId,type,coordAResId,scaleResId);
    //注册图元选中事件
    this.$Layout.nodeRegisterListener(this.nodeSelect);
    //注册图元坐标改变事件
    this.$Layout.nodeRegisterListener(this.nodeCoordChange);
    //注册晶圆旋转事件
    this.$Layout.nodeRegisterListener(this.waferRotation);
    //注册节点双击事件
    this.$Layout.nodeRegisterListener(this.nodeDbClick);
    //注册连线选中事件
    this.$Layout.linkRegisterListener(this.linkSelect);
    //注册连线双击事件
    this.$Layout.linkRegisterListener(this.linkDbClick);
  },
  /**
   * 在属性框中绘制引脚级视图
   */
  drawPin(resId,viewGroupResId,viewDiePartIndex,viewLinkPartIndex){
    /**
     * 调用插件进行画布初始化 传入参数
     * resId:当前工程资源id
     * type：0-晶圆级 1-floorplan级 2-引脚级
     * coordAResId:坐标系资源id
     * scaleResId：比例尺资源id
     * viewGroupResId:"",//双击预制件或连线所属组资源id
      viewDiePartIndex:"",//双击预制件的部件索引
      "viewLinkPartIndex:"",//双击连线的部件索引
     */
     this.$Layout.drawPin(resId,type,coordAResId,scaleResId,viewGroupResId,viewDiePartIndex,viewLinkPartIndex);
  },
  /**
   * die属性坐标修改
   * partIndex:布局信息部件索引
   * x:物理x绝对坐标
   * y:物理y绝对坐标
   */
  dieCoordChange(partIndex,x,y){
    this.$Layout.updateDieCoord(partIndex,x,y);
  },
  /**
   * die间距修改 间距均为物理属性需按当前比例尺进行转换
   * partIndex:布局信息部件索引
   * dieToDie:die与die之间的间距(um)
   * dieToPassive:die与无源之间的间距(um)
   * passiveToPassive:无源与无源组件之间的间距(um)
   */
   dieConstraintChange(partIndex,dieToDie,dieToPassive,passiveToPassive){
    this.$Layout.updateviewDieConstraintForm(partIndex,dieToDie,dieToPassive,passiveToPassive);
  },
   /**
   * die边距修改 边距均为物理属性需按当前比例尺进行转换
   * partIndex:布局信息部件索引
   * "margiLleft":""//相对基板左边距（20 nm）
      "marginRight":""//相对基板右边距（20 nm）
      "marginTop":""//相对基板上边距（20 nm）
      "marginBottom":""//相对基板下边距（20 nm）
   */
   diemarginChange(partIndex,margiLleft,marginRight,marginTop,marginBottom){
    this.$Layout.updateviewDieConstraintForm(partIndex,margiLleft,marginRight,marginTop,marginBottom);
  },
  /**
   * 连线样式修改 涉及到长宽均为物理属性，需按照比例尺换算
   * partIndex:布局信息部件索引
   * "length": "1 mm" //线条长度
      "width": "1 mm"//线条宽度
      "color": ""//线条颜色
      "bash":""//连线样式
   */
  linkStyleChange(partIndex,length,width,color,bash){
    this.$Layout.updateLinkConstraint(partIndex,length,width,color,bash);
  },
  /**
   * 保存当前布局编辑信息
   * type: 0-只保存不生成类原理图 1-保存且生成类原理图
   */
  projectSave(type){
    /**
     * "resId":"123",//项目工程ID
        "coordAResId":"0", //坐标系资源id
        "scaleResId"："",//当前比例尺资源id
        "type":0 //0-只保存不生成类原理图 1-保存且生成类原理图
     */
    this.$Layout.layoutSave(resId,coordAResId,scaleResId,type);
  },
  /**
   * 与外部接口交互 弹出对应提示框供用户选择
   */
   projectShowSave(){

  },
    /**
   * 自动布局事件
   */
   autoLayout(){

  },
  nodeSelect(node){
    console.log("当前选中节点："+node);
  },
  /**
   * 节点坐标变更
   * 绘图插件捕获到当前节点被用户拖拽移动的事件，事件中经过移动后的坐标通过当前比例尺转换为物理坐标 然后触发调用当前函数处理
   * node为物理属性：{
  "partIndex":"10",//当前资源索引
  "type":"CPU",
  "name":"cpu0",
  "label":"",//图元显示名称
  "rotation":"90",//预制件旋转角度
  "physicPosition":{"x":110,"y":100,"z":200}, //物理坐标信息
    }
    */
  nodeCoordChange(node){
    console.log("坐标变动："+node);
  },
  /**
   * 晶圆旋转事件
   *
   */
  waferRotation(x,y,z){
    console.log("当前晶圆旋转度为 X:"+x+" Y:"+y+ "Z:"+z);
  },
  linkSelect(link){
    //1.进行连线属性面板展示
  },
  /**
   * 节点双击事件
   * ｛
   *    "partIndex":"10",//当前资源索引
  "type":"CPU",
  "name":"cpu0",
    * ｝
    */
  nodeDbClick(node){
    console.log("当前节点触发双击事件:"+node);
  },
  /**
   * 连线双击事件
   * ｛
   *    "partIndex":"",//当前资源索引
  "fromId":"",//开始节点
  "toId":"",//结束节点
  "formPort":"",//开始端口
  "toPort":"",//结束端口
  "linkName":"",//连线名称
    * ｝
    */
    linkDbClick(link){
    console.log("当前连线触发双击事件:"+node);
  },
  //连接websocket
  wsSubscribe(that)
  {
    //发起topic主题订阅
    let ws = that.$ws.getWs(that.canvasWs.connectName);
    if (!ws) {
      console.log("ws未连接");
    } else {
      let data = {"layout":(nodes)=>{
          let msg = {};
          msg.topic = "layout";
          msg.msg = nodes;
          // console.log(msg);
          that.canvasManager.wsCallback(msg);
      },"pin":(nodes)=>{
        that.canvasManager.wsCallback(nodes);
      },"coord":(nodes)=>{
        that.canvasManager.wsCallback(nodes);
      }}
      ws.subscribeToModel(that.canvasWs.topicName,data , {});
    }
  },
 // 取消订阅
  cancelSubscribe()
  {
    let ws = that.$ws.getWs(that.linkName);
    if (ws) {
      ws.unSubscribe(that.requstParams.chartTopic);
    }
  }
  ,
  },
}
</script>
<style lang="less" scoped>
.container {
  height: 100%;
  width: 100%;
  min-width: 1020px;
  min-height: 500px;
  // overflow: auto;

}
</style>
